#ifndef _VALUE_
#define _VALUE_

/****************************************************/
/* Value.h											*/
/* by Andy Albert Fuchs								*/
/* - Systemprogrammierung -							*/
/****************************************************/

#include <iostream>
#include <assert.h>
#include <math.h>
#include "TokenHierarchy.h"

using namespace std;

/****************************************************/
/* Exceptions										*/
/****************************************************/

class ValueException {
	char* msg;

public:
	ValueException(char* msg);
	virtual char* getMessage();
	void setMessage(char* msg);
};

class ValueInvalidModuloException : public ValueException {

public:	
	ValueInvalidModuloException();
	virtual char* getMessage();
	void setToken(Token* token);
};

class ValueDivisionByZeroException : public ValueException {

public:
	ValueDivisionByZeroException();
	virtual char* getMessage();
	void setToken(Token* token);
};

/****************************************************/
/* Funktionen										*/
/****************************************************/

// Keine


/****************************************************/
/* Enums											*/
/****************************************************/

class ValueType {
public:
	enum {
		INT,
		REAL,
		OPERATOR
	};
};

class OpType {
public:
	enum {
		NONE,
		PLUS,
		MINUS,
		MULTI,
		DEVIDE,
		DEVIDE2,
		MOD
	};
};


/****************************************************/
/* class Value										*/
/****************************************************/

class ValueReal;

class Value {
	int type;
	int opType;

public:
	// Konstruktoren/Destruktor
	Value(int opType, int type);

	virtual ~Value();

	//Methoden
	void checkForCasting(Value* value);
	virtual Value* getCopy() = 0;

	virtual Value* compute(Value* value) = 0;
	virtual void negate() = 0;

	// Getters
	virtual int getType() const;
	virtual int getOpType() const;

	// Setters
	virtual void setOpType(int opType);

	// �berladene Operatoren
	virtual operator ValueReal* () const = 0;
};


/****************************************************/
/* class ValueInt									*/
/****************************************************/

class ValueInt : public Value {
	int value;

public:
	ValueInt(int opType, int value);

	virtual Value* getCopy();

	virtual Value* compute(Value* value);
	virtual void negate();

	int getValue() const;

	operator ValueReal* () const;
};


/****************************************************/
/* class ValueReal									*/
/****************************************************/

class ValueReal : public Value {
	double value;

public:
	ValueReal(int opType, double value);

	virtual Value* getCopy();

	virtual Value* compute(Value* value);
	virtual void negate();

	double getValue() const;

	operator ValueReal* () const;
};


/****************************************************/
/* class ValueOp									*/
/****************************************************/

class ValueOp : public Value {
public:
	ValueOp(int opType);

private:
	virtual Value* getCopy();

	virtual Value* compute(Value* value);
	virtual void negate();

	operator ValueReal* () const;
};


/****************************************************/
/* �berladene Operatoren							*/
/****************************************************/

ostream& operator <<(ostream& cout, Value* value);
#endif // _VALUE_
